// ------------------------------------------------------------------------
// 项目名称：Canroc.Net
// 版权归属：Canroc（https://gitee.com/canroc）
// 
// 许可证信息
// Canroc.Net项目主要遵循 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-APACHE 文件。
// 
// 使用条款：
// 1.使用本项目应遵守相关法律法规和许可证的要求。
// 2.不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动。
// 3.任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任
// 
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
// 
// 其他重要信息
// Canroc.Net 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// ------------------------------------------------------------------------

using Canroc.Net.Application.ApplicationService.Dto;
using Canroc.Net.Application.SysMailService;
using Canroc.Net.Application.SysMailService.Dto;
using Canroc.Net.Application.SysMenuService;
using Canroc.Net.Application.SysMenuService.Dto;
using Canroc.Net.Application.SysUserService;
using Furion.JsonSerialization;
using System.Text.Json.Nodes;

// ReSharper disable once CheckNamespace
namespace Canroc.Net.Application.ApplicationService;

/// <summary>
///     系统应用服务
/// </summary>
[ApiDescriptionSettings("Default")]
public partial class SystemAppService(IServiceProvider serviceProvider) : IDynamicApiController
{
    /// <summary>
    ///     获取登录用户信息
    /// </summary>
    /// <returns></returns>
    public async Task<LoginUserInfoOutput?> GetLoginUserInfoAsync()
    {
        var userService = serviceProvider.GetRequiredService<SysUserAppService>();
        var user = await userService.GetDataAsync(UserManager.UserId);
        if (user is null)
            return null;

        return new LoginUserInfoOutput
        {
            UserId = user.Id,
            NickName = user.NickName,
            Phone = user.Phone,
            Avatar = user.Avatar,
            Org = user.OrgName,
            Roles = [.. user.RoleName.Split(",")]
        };
    }

    /// <summary>
    ///     获取登录用户所拥有的菜单
    /// </summary>
    /// <returns></returns>
    public async Task<List<LoginUserMenuOutput>?> GetLoginUserMenuAsync()
    {
        var sysMenuService = serviceProvider.GetRequiredService<SysMenuAppService>();
        return MenuToRoute(await sysMenuService.GetUserMenuAsync(UserManager.UserId, UserManager.IsSuperAdmin));
    }

    /// <summary>
    ///     获取登录用户所拥有的按钮
    /// </summary>
    /// <returns></returns>
    public async Task<Dictionary<string, List<string>>> GetLoginUserButtonAsync()
    {
        var sysMenuService = serviceProvider.GetRequiredService<SysMenuAppService>();
        return await sysMenuService.GetUserButtonAsync(UserManager.UserId, UserManager.IsSuperAdmin);
    }

    /// <summary>
    ///     获取当前用户未读站内信
    /// </summary>
    /// <returns></returns>
    public async Task<List<MailShortOutput>> GetUserNoReadMailsAsync()
    {
        var sysMailService = serviceProvider.GetRequiredService<SysMailAppService>();
        return await sysMailService.GetMailByUserIdAsync(UserManager.UserId, false);
    }

    /// <summary>
    ///     获取当前站内信信息
    /// </summary>
    /// <param name="mailId">站内信Id</param>
    /// <returns></returns>
    public async Task<MailOutput> GetMailByIdAsync(Guid mailId)
    {
        // 查询站内信信息
        var sysMailService = serviceProvider.GetRequiredService<SysMailAppService>();
        var mail = await sysMailService.GetDataAsync(mailId) ?? throw Oops.Oh("站内信不存在！");

        // 标记为已读
        var mailAndUserRep = serviceProvider.GetRequiredService<SqlSugarRepository<RelMailUser>>();
        _ = await mailAndUserRep.UpdateAsync(imu => new RelMailUser { IsRead = true, ReadTime = DateTime.Now },
            imu => imu.MailId == mailId && imu.UserId == UserManager.UserId);

        return mail;
    }

    #region 内部函数

    /// <summary>
    ///     将菜单转化为前台路由
    /// </summary>
    /// <param name="menus">系统菜单</param>
    /// <returns></returns>
    [NonAction]
    private static List<LoginUserMenuOutput>? MenuToRoute(List<MenuOutput>? menus)
    {
        if (menus is null)
            return null;

        List<LoginUserMenuOutput> routes = [];
        menus.ForEach(menu =>
        {
            var hasParams = !menu.Params.IsNullOrEmpty() && menu.Params != "{}";
            routes.Add(new LoginUserMenuOutput
            {
                Path =
                    hasParams && menu.SplicingMethod == MenuSplicingMethodEnum.Params
                        ? SplicingPathParams(menu.Path, menu.Params)
                        : menu.Path,
                Name = menu.Name,
                Redirect = !menu.Redirect.IsNullOrEmpty() ? menu.Redirect : null,
                Component = !menu.Component.IsNullOrEmpty() ? menu.Component : null,
                Meta = new MetaOutput
                {
                    Icon = menu.Icon,
                    Title = menu.Title,
                    ActiveMenu = !menu.ActiveMenu.IsNullOrEmpty() ? menu.ActiveMenu : null,
                    IsLink = menu.Link,
                    IsHide = menu.IsHide,
                    IsFull = menu.IsFull,
                    IsAffix = menu.IsAffix,
                    IsKeepAlive = menu.IsKeepAlive,
                    Params = hasParams ? JSON.Deserialize<object>(menu.Params) : null,
                    SplicingMethod = menu.SplicingMethod.ToString()
                },
                Children = MenuToRoute(menu.Children)
            });
        });

        return routes;
    }

    /// <summary>
    ///     拼接路由参数
    /// </summary>
    /// <param name="path">路由</param>
    /// <param name="paramsStr">参数</param>
    /// <returns></returns>
    [NonAction]
    public static string SplicingPathParams(string path, string paramsStr)
    {
        // 反序列化参数
        var paramsObj = JSON.Deserialize<JsonObject>(paramsStr);
        return paramsObj is null
            ? path
            :
            // 提取参数的属性
            paramsObj.Aggregate(path, (current, item) => current + $"/:{item.Key}");
    }

    #endregion
}